var express = require('express');
var bodyParser = require('body-parser');
var db = require('./db');

var app = express();
app.set('port', process.argv[2] || 3000);

db.connect(() => { throw 'mongodb connection failed!' }, () => {
	app.listen(app.get('port'), () => {
		console.log('Express started on http://localhost:' +
			app.get('port') + '; press Ctrl-C to terminate.');
	})
});

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));

// parse application/json
app.use(bodyParser.json());

// static files
app.use(express.static('web'));

// API response
app.all(/\/rsms\/api\/.+/, (req, res) => {
	var param = req.method === 'GET' ? 'query' : 'body';
	//console.log(req[param]);
	invoke_db_api(req.path, req[param]).then(result => {
		res.json({ result });
	}, error => {
		res.json({ error: error.toString() });
	});
});

// custom 404 page
app.use((req, res) => {
	res.type('text/plain');
	res.status(404);
	res.send('404 - Not Found');
});

// custom 500 page
app.use((err, req, res, next) => {
	console.error(err.stack);
	res.type('text/plain');
	res.status(500);
	res.send('500 - Server Error');
});

//====================================

function invoke_db_api(path, args) {
	var promise = new Promise((res, rej) => {
		var path_arr = path.substr(1).split('/');
		path_arr.shift();
		path_arr.shift();
		var api_name = path_arr.join('_');
		var api = db.api[api_name];
		if (!api) rej('invalid api');
		var token = args.token;
		db.check_privilege(api_name, token).then(user => {
			if (!user) rej('denied');
			var api_params = api.toString()
				.match(/\(.*?\)/)[0].replace(/[()\s]/g, '').split(',');
			if (api_params.length === 1 && api_params[0] === '') {
				res(api(user));
			}
			else {
				res(api.apply(null, api_params.map(e => {
					if (e === '_self') return user;
					if (e.startsWith('$')) return JSON.parse(args[e.substr(1)]);
					return args[e];
				})));
			}
		});
	});
	return promise;
};
